﻿#ifndef XMD5_H
#define XMD5_H

#include <string>
#include <fstream>

/*类型定义 */
typedef unsigned char uchar;
typedef unsigned int uint32;

using std::string;
using std::ifstream;

/* MD5 声明 */
class XMD5 {
public:
	XMD5();
	XMD5(const void* input, size_t length);
	XMD5(const string& str);
	XMD5(ifstream& in);
	void update(const void* input, size_t length);
	void update(const string& str);
	void update(ifstream& in);
	/*返回消息摘要*/
	const uchar* digest();
	//转String输出
	std::string toString();
	//重置状态
	void reset();
public: 
	//获得32位md5值
	static std::string String(const void* input, size_t length);
	static std::string String(const string& str);
	static std::string file(ifstream& in);
	static std::string file(const string& path);
private:
	void update(const uchar* input, size_t length);
	void final();
	void transform(const uchar block[64]);
	void encode(const uint32* input, uchar* output, size_t length);
	void decode(const uchar* input, uint32* output, size_t length);
	string bytesToHexString(const uchar* input, size_t length);

	/* class uncopyable */
	XMD5(const XMD5&);
	XMD5& operator=(const XMD5&);

private:
	uint32 _state[4]; /* state (ABCD) */
	uint32 _count[2]; /* number of bits, modulo 2^64 (low-order word first) */
	uchar _buffer[64]; /* input buffer */
	uchar _digest[16]; /* message digest */
	bool _finished;   /* calculate finished ? */

	static const uchar PADDING[64]; /* padding for calculate */
	static const char HEX[16];
	enum { BUFFER_SIZE = 1024 };
};

#endif /*MD5_H*/